package com.wb3.meta.config.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Configuration
public class TTSUtils {

    @Value("${tts.callUrl}")
    private String ttsUrl;
    @Value("${tts.storeUrl}")
    private String storeUrl;

    @Value("${tts.token}")
    private String token;

    private static CloseableHttpClient httpClient;

    static {
        // 创建线程安全的 CloseableHttpClient
        httpClient = HttpClients.custom()
                .setDefaultRequestConfig(RequestConfig.custom()
                        .setConnectTimeout(35000)
                        .setConnectionRequestTimeout(35000)
                        .setSocketTimeout(60000)
                        .build())
                .build();
    }

    public Event getStoreByWorldIdAndToysAudioId(int toysAudioId , String worldId) throws IOException {
        JSONObject jb = new JSONObject();
        jb.put("chara_id", toysAudioId);
        jb.put("world_id", worldId);
        String url = storeUrl + "zzworld/gen_event";
        try (CloseableHttpResponse response = sendPost(httpClient, url, null, jb.toString())) {
            int statusCode = response.getStatusLine().getStatusCode();

            if (statusCode == 200) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
                StringBuilder responseString = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    responseString.append(line);
                }

                JSONObject responseObject = JSONObject.parseObject(responseString.toString());
                return fromJson(responseObject);
            } else if (statusCode == 500) {
                // Return an empty Event object
                return null;
            } else {
                // Handle other status codes
                throw new IOException("Unexpected status code: " + statusCode);
            }
        }
    }

    public ResponseInfo testToTTS(String content, String type) throws IOException {
        JSONObject jb = new JSONObject();
        jb.put("text", content);
        jb.put("speaker", type);
        if("dayi".equals(type)){
            jb.put("fewshot", "true");
        }
        String data = jb.toJSONString();
        log.info(data);

        Map<String, String> headers = new HashMap<>();
        // 设置其他请求头
        headers.put("Authorization", token);

        // 使用不同的文件名，以防止并发写入同一个文件
        String fileName = "audio_" + System.currentTimeMillis() + ".mp3";

        return sendPostRequest(ttsUrl, headers, data, fileName);
    }

    @Data
    public static class ResponseInfo {
        private final String duration;
        private final File audioFile;

        public ResponseInfo(String duration, File audioFile) {
            this.duration = duration;
            this.audioFile = audioFile;
        }
    }
    @Data
    public static
    class Event {
        String location;
        String description;
        List<Participant> participants;
        List<Action> actions_list;
        public Event(){}
        public Event(String location, String description, List<Participant> participants, List<Action> actions_list) {
            this.location = location;
            this.description = description;
            this.participants = participants;
            this.actions_list = actions_list;
        }


    }
    public Event fromJson(JSONObject jsonObject) {
        String location = jsonObject.getString("location");
        String description = jsonObject.getString("description");

        List<Participant> participants = new ArrayList<>();
        JSONArray participantsJsonArray = jsonObject.getJSONArray("participants");
        for (int i = 0; i < participantsJsonArray.size(); i++) {
            participants.add(new Participant(participantsJsonArray.getString(i)));
        }

        List<Action> actions_list = new ArrayList<>();
        JSONArray actionsJsonArray = jsonObject.getJSONArray("actions_list");
        for (int i = 0; i < actionsJsonArray.size(); i++) {
            JSONObject actionJson = actionsJsonArray.getJSONObject(i);
            String action = actionJson.getString("action");
            int favorability = actionJson.getInteger("favorability");
            String des = actionJson.getString("des");
            actions_list.add(new Action(action, favorability, des));
        }

        return new Event(location, description, participants, actions_list);
    }
    @Data
    // Class to represent participants
    public static class Participant {
        String name;
        public Participant() {
        }
        public Participant(String name) {
            this.name = name;
        }
    }

    @Data
    // Class to represent actions
    public static class Action {
        String action;
        int favorability;
        String des;
        public Action() {
        }
        public Action(String action, int favorability, String des) {
            this.action = action;
            this.favorability = favorability;
            this.des = des;
        }
    }
    static ResponseInfo sendPostRequest(String url, Map<String, String> headers, String jsonData, String fileName) throws IOException {
        try (CloseableHttpResponse response = sendPost(httpClient, url, headers, jsonData)) {
            int statusCode = response.getStatusLine().getStatusCode();

            if (statusCode == 200) {
                // 获取特定响应头
                String durationHeader = response.getFirstHeader("duration") != null ? response.getFirstHeader("duration").getValue() : "";

                // 获取文件并转化为 MultipartFile
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    InputStream audioInputStream = entity.getContent();
                    // 将 InputStream 写入文件
                    File audioFile = new File(fileName);
                    try (OutputStream outputStream = new FileOutputStream(audioFile)) {
                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        while ((bytesRead = audioInputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                        }
                    }

                    return new ResponseInfo(durationHeader, audioFile);
                } else {
                    // Handle the case where the response entity is null
                    throw new IOException("No file content in the response.");
                }
            } else if (statusCode == 500) {
                // 返回空的 ResponseInfo 对象
                return new ResponseInfo("", null);
            } else {
                // 处理其他状态码
                throw new IOException("Unexpected status code: " + statusCode);
            }
        }
    }

    private static CloseableHttpResponse sendPost(CloseableHttpClient httpClient, String url, Map<String, String> headers, String jsonData) throws IOException {
        HttpPost httpPost = new HttpPost(url);

        // 设置请求头
        if (headers != null) {
            headers.forEach(httpPost::setHeader);
        }
//        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000).setConnectionRequestTimeout(35000).setSocketTimeout(60000).build();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(0)  // 不限制连接超时
                .setConnectionRequestTimeout(0)  // 不限制连接请求超时
                .setSocketTimeout(0)  // 不限制套接字超时
                .build();

        httpPost.setConfig(requestConfig);
        httpPost.setHeader("Content-Type", "application/json");
        httpPost.setEntity(new StringEntity(jsonData,"UTF-8"));

        return httpClient.execute(httpPost);
    }

    static byte[] readAllBytes(InputStream inputStream) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int bytesRead;

        while ((bytesRead = inputStream.read(buffer)) != -1) {
            baos.write(buffer, 0, bytesRead);
        }

        return baos.toByteArray();
    }
    public static String removeBrackets(String input) {
        // 定义正则表达式匹配全角和半角括号及其内部内容
        String regex = "[（(][^）)]*[）)]";

        // 编译正则表达式
        Pattern pattern = Pattern.compile(regex);

        // 创建匹配器
        Matcher matcher = pattern.matcher(input);

        // 使用 replaceAll 方法替换匹配到的括号及其内部内容
        String result = matcher.replaceAll("");

        return result;
    }
    public static void main(String[] args) {
        // 示例字符串
        String input = "Hello (world)， this is （a test） string.";

        // 调用方法移除括号及其内部内容
        String output = removeBrackets(input);

        // 打印结果
        System.out.println("Original string: " + input);
        System.out.println("String without mixed brackets: " + output);
    }
}
